package algotradingfx.strategies;

import java.util.ArrayList;
import java.util.Vector;

import algotradingfx.utils.Constants;
import algotradingfx.utils.FXAsset;
import atp.client.trading.methods.TradingMethod.Side;
import atp.client.trading.methods.TradingMethod.Type;
import atp.client.trading.strategies.StrategyPush;
import atp.commons.util.StrategyInfo;
import atp.commons.util.Tick;

public class MovingAveragePushStrategy extends StrategyPush {
	private static final long serialVersionUID = 1L;
	private static final String STRATEGY_NAME = "MovingAveragePushStrategy";
	public double average = 0.0;
	public double closePrice = 0.0;
	public double openPrice = 0.0;
	public Vector<String> positionChecker = new Vector<String>();
	public Vector<String> positions = new Vector<String>();
	public double previousAsk = 0.0;

	public MovingAveragePushStrategy(String ssID, String password) {
		super(new StrategyInfo(STRATEGY_NAME), ssID, password);
	}

	private double computeAverage(Tick[] buffer) {
		double average = 0.0;
		int size = buffer.length;
		for (int i = 0; i < buffer.length; i++) {
			average += buffer[i].getAsk();
		}
		average = average / size;
		return average;
	}

	private void computePositionPips() {
		ArrayList<String> checker = new ArrayList<String>(positionChecker.size());
		for (int i = 0; i < positionChecker.size(); i++) {
			checker.add(positionChecker.get(i));
		}
		if (!positionChecker.isEmpty()) {
			for (String ticket : checker) {
				forex.select(ticket);
				System.out.println("OPEN: " + forex.getOpenPrice() + " CLOSE: " + forex.getClosePrice());
				System.out.println("IS OPEN: " + forex.isOpen());
				System.out.println("OUTSTANDING POSITION: " + forex.getOutstandingPosition());

				if (forex.getOpenPrice() != 0.0 && forex.getClosePrice() != 0.0) {
					if (forex.getSide().equals(Side.BUY)) {
						double pips = forex.getClosePrice() - forex.getOpenPrice();
						System.out.println("MovingAverageStrategy: Ticket: " + ticket + ", made " + pips + " pips");
						positionChecker.remove(ticket);
					} else {
						double pips = forex.getOpenPrice() - forex.getClosePrice();
						System.out.println("MovingAverageStrategy: Ticket: " + ticket + ", made " + pips + " pips");
						positionChecker.remove(ticket);
					}
				}
			}
		}
	}

	private void doRun(Object o) {
		if (o instanceof Tick) {
			Tick t = (Tick) o;
			if (previousAsk == 0.0) {
				previousAsk = t.getAsk();
			}
			average = computeAverage(getTickHistory(FXAsset.EURUSD.toString(), Constants.MOCK_BROKER));

			System.out.println("Average: " + average);
			System.out.println("Previous Tick: " + previousAsk);
			System.out.println("Current Tick: " + t.getAsk());

			if (positions.isEmpty()) {

				if (previousAsk > average && t.getAsk() < average) {

					String ticket = forex.send(FXAsset.EURUSD.toString(), Type.MARKET, Side.SELL, 100000, 0.0, 0.0,
					        Constants.MOCK_BROKER);
					System.out.println("MovingAverageStrategy: Opened a new position: SELL: EURUSD: ticket: " + ticket);
					positions.add(ticket);
					positionChecker.add(ticket);

				} else if (previousAsk < average && t.getAsk() > average) {

					String ticket = forex.send(FXAsset.EURUSD.toString(), Type.MARKET, Side.BUY, 100000, 0.0, 0.0,
					        Constants.MOCK_BROKER);
					System.out.println("MovingAverageStrategy: Opened a new position: BUY: EURUSD: ticket: " + ticket);
					positions.add(ticket);
					positionChecker.add(ticket);

				}

			} else {

				forex.select(positions.get(0));

				if (previousAsk > average && t.getAsk() < average) {

					if (forex.isOpen() && forex.getSide().equals(Side.BUY)) {

						forex.closePosition();
						System.out.println("MovingAverageStrategy: Closed position: SELL: EURUSD: ticket: "
						        + positions.get(0));
						positions.remove(0);
					}
				}

				if (previousAsk < average && t.getAsk() > average) {

					if (forex.isOpen() && forex.getSide().equals(Side.SELL)) {

						forex.closePosition();
						System.out.println("MovingAverageStrategy: Closing a position: BUY: EURUSD: ticket: "
						        + positions.get(0));
						positions.remove(0);
					}
				}
			}

			previousAsk = t.getAsk();
			computePositionPips();
		}
	}

	@Override
	public void initialise() {
		declare(FXAsset.EURUSD.toString(), Constants.MOCK_BROKER);
		declare(FXAsset.USDJPY.toString(), Constants.MOCK_BROKER);
	}

	@Override
	public boolean run(Object o) {
		doRun(o);
		return false;
	}
}